cmake_minimum_required(VERSION 3.12)

# set build type
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  message("Setting build type to 'Debug' as none was specified.")
  set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE)
  # Set the possible values of build type for cmake-gui
  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
    "MinSizeRel" "RelWithDebInfo")
endif()

project(
  hp_filter
  DESCRIPTION "hp_filter is a high-performance package filter."
  LANGUAGES CXX
  VERSION 1.0.0
)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")

find_package(PCAP REQUIRED)
find_package(Threads REQUIRED)

# source files
set(
  SOURCES
  src/core/packet.cpp
  src/core/device_manager.cpp
  src/core/pcap_device.cpp
  src/core/gateway_config.cpp
  src/core/packet_dispatcher.cpp
  src/filters/types.cpp
  src/filters/simple_filter_engine.cpp
  src/filters/filter_worker.cpp
  src/filters/filter_thread_pool.cpp
  src/utils/logger.cpp
  src/utils/command_line_parser.cpp
)

set(
  HEADERS
  include/core/IDevice.h
  include/core/device_manager.h
  include/core/packet.h
  include/core/pcap_device.h
  include/core/gateway_config.h
  include/core/packet_dispatcher.h
  include/filters/types.h
  include/filters/filter_engine.h
  include/filters/simple_filter_engine.h
  include/filters/filter_worker.h
  include/network/protocols.h
  include/network/types.h
  include/utils/logger.h
  include/utils/command_line_parser.h
  include/utils/spsc_queue.h
  include/utils/spsc_queue.ipp
)

add_library(${PROJECT_NAME}_static STATIC ${SOURCES} ${HEADERS})

set_target_properties(${PROJECT_NAME}_static PROPERTIES
  OUTPUT_NAME ${PROJECT_NAME}
  ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
)

target_compile_features(${PROJECT_NAME}_static PRIVATE cxx_std_20)
target_compile_options(${PROJECT_NAME}_static PRIVATE
    -Wall
    -Wextra
    -Wpedantic
)

target_link_libraries(${PROJECT_NAME}_static PRIVATE
    ${PCAP_LIBRARY}
    Threads::Threads
)

target_include_directories(
  ${PROJECT_NAME}_static PUBLIC
  ${CMAKE_CURRENT_SOURCE_DIR}/include
)

# create executable file
add_executable(${PROJECT_NAME} src/main.cpp)

# compile flags
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20)
target_compile_options(${PROJECT_NAME} PRIVATE
    -Wall
    -Wextra
    -Wpedantic
)

# link libraries
target_link_libraries(${PROJECT_NAME} PRIVATE
  ${PROJECT_NAME}_static
  ${PCAP_LIBRARY}
  Threads::Threads
)

target_include_directories(
  ${PROJECT_NAME} PUBLIC
  ${CMAKE_CURRENT_SOURCE_DIR}/include
)

# test
option(BUILD_TESTS "Build tests" ON)
if(BUILD_TESTS)
  add_subdirectory(test)
endif()
